package com.wh1200.mybatis.xmlless.model.component

import com.wh1200.mybatis.xmlless.dialect.DialectFactory
import com.wh1200.mybatis.xmlless.model.MethodInfo
import com.wh1200.mybatis.xmlless.model.TableName
import com.wh1200.mybatis.xmlless.model.XmllessTableInfo
import com.wh1200.mybatis.xmlless.util.DbTypeHolder
import net.sf.jsqlparser.expression.Expression

/**
 *
 * @author 吴昊
 * @date 2023/12/5 9:59
 * @since v0.0.0
 * @version 1.0
 */
class JoinOnConditionDeclaration(
    private val originTableInfo: XmllessTableInfo,
    var originTable: TableName,
    private val targetTableInfo: XmllessTableInfo?,
    private val originExpression: Expression,
    private val targetTable: TableName,
    private val targetExpression: Expression,
    private val isJson: Boolean = false,
    private val isTargetJson: Boolean = false
) {

  fun toSql(methodInfo: MethodInfo): String {
    val visitor = ReplacePropertyToJoinColumnVisitor(originTableInfo, originTable, methodInfo.dbType)
    originExpression.accept(visitor)
    if (targetTableInfo != null) {
      val targetVisitor = ReplacePropertyToJoinColumnVisitor(targetTableInfo, targetTable, methodInfo.dbType)
      targetExpression.accept(targetVisitor)
    }
    return toSql(originExpression, targetExpression)
  }

  fun toSql(): String {
    return toSql(originExpression, targetExpression)
  }

  private fun toSql(origin: Expression, target: Expression): String {
    if (isJson) {
      return DialectFactory.getDialect(DbTypeHolder.getDBType()).createJoinJsonArrayElementEqual(
          origin.toString(), target.toString()
      )
    } else if (isTargetJson) {
      return DialectFactory.getDialect(DbTypeHolder.getDBType()).createJoinJsonArrayElementEqual(
          target.toString(), origin.toString()
      )
    }
    return "$target = $origin"
  }

}
